package com.threegroup.admin.service;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.threegroup.common.dto.OrdersPageDTO;
import com.threegroup.admin.utils.AssertUtil;
import com.threegroup.common.dao.OrdersDao;
import com.threegroup.common.dto.OrderDetailDTO;
import com.threegroup.common.dto.OrdersDTO;
import com.threegroup.common.dto.OrdersQueryDTO;
import com.threegroup.common.entity.OrdersEntity;
import com.threegroup.common.redis.RedisUtils;
import com.threegroup.common.utils.OrderNumUtils;
import com.threegroup.common.utils.Result;
import com.threegroup.common.validator.AssertUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;

@Service
public class OrdersService {
    @Resource
    private OrdersDao ordersDao;

    @Resource
    private OrderDetailService orderDetailService;

    @Resource
    private RedisUtils redisUtils;

    //客户
    //@Resource
    //private UserDao userDao;

    //@Resource
    //private AddressBookDao addressBookDao;

    /**
    添加订单
        1.参数校验
            下单用户
                非空 用户存在
            地址id
                非空 该地址id存在
            下单时间
                空 设置默认值
                非空 合法
            订单号
                空 设置默认
                非空 合法
            订单状态
                空 设置默认为 1 待付款
                非空 合法
            结账时间
                空
                非空 合法
            支付方式
                空
                非空 合法
            实收金额
                空
                非空 合法
            备注
                空
                非空
            phone
                空 通过地址id 拿到phone
                非空  合法
            address
                空 通过地址id 拿到address
                非空  合法
            consignee
                空 通过地址id 拿到consignee
                非空  合法
            userName
                空 通过userId拿到userName
          2.执行添加操作

     **/
    @Transactional(propagation = Propagation.REQUIRED)
    public Result addOrders(OrdersDTO ordersDTO) {

        Result result = new Result();

        //抽取数据
        String number = ordersDTO.getNumber();
        Integer status = ordersDTO.getStatus();
        Long userId = ordersDTO.getUserId();
        Long addressBookId = ordersDTO.getAddressBookId();
        Date orderTime = ordersDTO.getOrderTime();
        Date checkoutTime = ordersDTO.getCheckoutTime();
        Integer payMethod = ordersDTO.getPayMethod();
        BigDecimal amount = ordersDTO.getAmount();
        String remark = ordersDTO.getRemark();
        String phone = ordersDTO.getPhone();
        String address = ordersDTO.getAddress();
        String consignee = ordersDTO.getConsignee();
        String userName = ordersDTO.getUserName();
        List<OrderDetailDTO> orderDetails = ordersDTO.getOrderDetails();

        /**用户Id
            非空 存在
         **/
        //AssertUtils.isNull(userId,"用户DI为空");
        //UserEntity userEntity = userDao.selectById(userId);
        //AssertUtils.isNull(userEntity,"该用户不存在");

        /**
         * userName
         *         空 通过userId拿到userName
         */
        //if (null==userName){
        //    userName=userEntity.getName();
        //}

        /**
         * 地址id
         *                 非空 该地址id存在
         */
        //AssertUtils.isNull(addressBookId,"地址信息DI为空");
        //AddressBookEntity addressBookEntity = addressBookDao.selectById(addressBookId);
        //AssertUtils.isNull(addressBookEntity,"该地址信息不存在");

        /**
         * phone
         *                 空 通过地址id 拿到phone
         *                 非空  合法
         */
        //空 通过地址id 拿到phone
        //if (null==phone){
        //    phone=addressBookEntity.getPhone();
        //}
        //非空  合法
        AssertUtil.isTrue(!Pattern.matches("^1[3-9]\\d{9}$", phone),"手机号码格式有误");

        /**
         * address
         *                 空 通过地址id 拿到address
         *                 非空  合法
         */
        //address
        //空 通过地址id 拿到address
        //if (null==address){
        //    address=addressBookEntity.getCityName()+addressBookEntity.getDistrictName()+addressBookEntity.getProvinceName()+addressBookEntity.getDetail();
        //}
        //非空  合法

        /**
         * consignee
         *                 空 通过地址id 拿到consignee
         *                 非空  合法
         */
        //consignee
        //空 通过地址id 拿到consignee
        //if (null==consignee){
        //    consignee=addressBookEntity.getConsignee();
        //}
        //非空  合法

        /**
         * 下单时间
         *                 空 设置默认值
         *                 非空 合法
         */
        if (null==orderTime){
            orderTime=new Date();
        }

        /**
         * 订单号
         *                 空 设置默认
         *                 非空 合法
         */
        if (null==number||number.replace(" ","").equals("")){
            number=OrderNumUtils.getOrderNum();
        }

        /**
         * 订单状态
         *                 空 设置默认为 1 待付款
         *                 非空 合法
         */
        if (null==status){
            status=1;
        }
        AssertUtil.isTrue(!(status==1||status==2||status==3||status==4||status==5),"订单状态有误");

        /**
         * 结账时间
         *      空 非订单状态为1的不能为空
         *      非空 订单状态为结账时间需为空
         */
        if (null==checkoutTime){
            AssertUtil.isTrue(status!=1,"该订单已支付，结账时间不能为空");
        }
        if (status==1){
            checkoutTime=null;
        }

        /**
         * 支付方式
         *                 空 支付状态为1可以为空，其他不合法
         *                 非空 合法
         */
        if (null==payMethod){
            AssertUtil.isTrue(status!=1,"已支付，无支付方式，不合法");
        }
        AssertUtil.isTrue(!(payMethod==1||payMethod==2),"支付方式有误");

        /**
         * 实收金额
         *      传入是否为空
         *          空 设置默认
         *          非空
         */
        if (null==amount){
            for (OrderDetailDTO orderDetail : orderDetails) {
                amount.add(orderDetail.getAmount());
            }
        }
        AssertUtil.isTrue(null==amount||amount.compareTo(BigDecimal.ZERO)<=0,"实收金额有误,不能为0和负数");

        OrdersEntity ordersEntity = new OrdersEntity();
        ordersEntity.setAddress(address);
        ordersEntity.setAmount(amount);
        ordersEntity.setOrderTime(orderTime);
        ordersEntity.setAddressBookId(addressBookId);
        ordersEntity.setCheckoutTime(checkoutTime);
        ordersEntity.setNumber(number);
        ordersEntity.setUserId(userId);
        ordersEntity.setPayMethod(payMethod);
        ordersEntity.setRemark(remark);
        ordersEntity.setPhone(phone);
        ordersEntity.setUserName(userName);
        ordersEntity.setConsignee(consignee);
        ordersEntity.setStatus(status);

        int num = ordersDao.insertSelective(ordersEntity);
        AssertUtil.isTrue(num!=1,"订单添加失败");

        //获取订单主键(后台管理系统不需要添加订单时同时添加订单详情,web层需要)
        Long id = ordersEntity.getId();

        /**
         * 订单明细(后台管理系统不需要添加订单时同时添加订单详情,web层需要)
         *
         *      在订单添加成功的情况下添加
         *          判断订单是否添加成功
         */
        //AssertUtils.isNull(orderDetails,"订单明细不能为空");
        //AssertUtils.isListEmpty(orderDetails,"订单明细不能为空");
        //for (OrderDetailDTO orderDetail : orderDetails) {
        //    AssertUtil.isTrue(orderDetailService.addOrderDetail(orderDetail, id).getCode()!=0 ,"订单明细有误");
        //}

        redisUtils.set("ORDER:"+number,number,RedisUtils.HOUR_HALF_EXPIRE);

        return result;
    }

    /** 修改订单
        1.参数校验
            订单id
                非空 存在
            下单用户
                空
                非空 用户存在
            地址id
                空
                非空 该地址id存在
            下单时间
                空
                非空 合法
            订单号
                空
                非空 合法
            订单状态
                空
                非空 合法
            结账时间
                空
                    状态非1
                        并且原来的订单结账时间为空，报错
                非空
                    状态为1
                        设置为null
                    状态非1
                        合法
            支付方式
                空
                    状态非1
                        并且原来的支付方式为空，报错
                非空
                    状态为1
                        设置为null
                    状态非1
                    合法
            实收金额
                 空
                    状态非1
                        并且原来的订单结账时间为空，报错
                非空
                    状态为1
                        设置为null
                    状态非1
                        合法
            备注
                空
                非空
            phone
                空 通过地址id 拿到phone
                非空  合法
            address
                空 通过地址id 拿到address
                非空  合法
            consignee
                空 通过地址id 拿到consignee
                非空  合法
            userName
                空 通过userId拿到userName
     2.执行更新操作

     **/
    @Transactional(propagation = Propagation.REQUIRED)
    public Result updeteOrders(OrdersDTO ordersDTO) {

        Result result = new Result();

        //抽取数据
        Long id = ordersDTO.getId();
        String number = ordersDTO.getNumber();
        Integer status = ordersDTO.getStatus();
        Long userId = ordersDTO.getUserId();
        Long addressBookId = ordersDTO.getAddressBookId();
        Date orderTime = ordersDTO.getOrderTime();
        Date checkoutTime = ordersDTO.getCheckoutTime();
        Integer payMethod = ordersDTO.getPayMethod();
        BigDecimal amount = ordersDTO.getAmount();
        String remark = ordersDTO.getRemark();
        String phone = ordersDTO.getPhone();
        String address = ordersDTO.getAddress();
        String consignee = ordersDTO.getConsignee();
        String userName = ordersDTO.getUserName();



        /**
         * 订单Id
         *    非空 存在
         */
        AssertUtils.isNull(id,"订单ID为空");
        OrdersEntity ordersTemp = ordersDao.selectByPrimaryKey(id);
        AssertUtils.isNull( ordersTemp,"待更新订单不存在");

        /**用户Id
         非空 存在
         **/
        //if (null==userId){
        //    userId=ordersTemp.getUserId();
        //}
        //UserEntity userEntity = userDao.selectById(userId);
        //AssertUtils.isNull(userEntity,"该用户不存在");

        /**
         * userName
         *         空 通过userId拿到userName
         */
        //if (null==userName){
        //    userName=userEntity.getName();
        //}

        /**
         * 地址id
         *                 非空 该地址id存在
         */
        //if (null==addressBookId){
        //    addressBookId=ordersTemp.getAddressBookId();
        //}
        //AddressBookEntity addressBookEntity = addressBookDao.selectById(addressBookId);
        //AssertUtils.isNull(addressBookEntity,"该地址信息不存在");

        /**
         * phone
         *                 空 通过地址id 拿到phone
         *                 非空  合法
         */
        //空 通过地址id 拿到phone
        //if (null==phone){
        //    phone=addressBookEntity.getPhone();
        //}
        //非空  合法
        if (null!=phone){
            AssertUtil.isTrue(!Pattern.matches("^1[3-9]\\d{9}$", phone),"手机号码格式有误");
        }



        /**
         * address
         *                 空 通过地址id 拿到address
         *                 非空  合法
         */
        //address
        //空 通过地址id 拿到address
        //if (null==address){
        //    address=addressBookEntity.getCityName()+addressBookEntity.getDistrictName()+addressBookEntity.getProvinceName()+addressBookEntity.getDetail();
        //}
        //非空  合法

        /**
         * consignee
         *                 空 通过地址id 拿到consignee
         *                 非空  合法
         */
        //consignee
        //空 通过地址id 拿到consignee
        //if (null==consignee){
        //    consignee=addressBookEntity.getConsignee();
        //}
        //非空  合法

        /**
         * 下单时间
         *                 空 设置默认值
         *                 非空 合法
         */
        if (null!=orderTime){
            orderTime=ordersTemp.getOrderTime();
        }

        /**
         * 订单号
         *                 空 设置默认
         *                 非空 合法
         */
        if (null!=number){
            number = OrderNumUtils.getOrderNum();
        }


        /**
         * 订单状态
         *                 空
         *                 非空 合法
         */
        if (null==status){
            status=ordersTemp.getStatus();
        }
        AssertUtil.isTrue(!(status==1||status==2||status==3||status==4||status==5),"订单状态有误");

        /** 结账时间
         空
            状态非1
                并且原来的订单结账时间为空，报错
         非空
            状态为1
                设置为null
            状态非1
                合法
         */
        if (null==checkoutTime){
            if (null==ordersTemp.getCheckoutTime()){
                AssertUtil.isTrue(status!=1,"该订单已支付，结账时间不能为空");
            }else {
                checkoutTime=ordersTemp.getCheckoutTime();
            }
        }
        if (status==1){
            checkoutTime=null;
        }

        /**
         * 支付方式
            空
                状态非1
                    并且原来的支付方式为空，报错
            非空
                状态为1
                    设置为null
                状态非1
                    合法
         */
        if (null==payMethod){
            if (null==ordersTemp.getPayMethod()){
                AssertUtil.isTrue(status!=1,"已支付，无支付方式，不合法");
            }else {
                payMethod=ordersTemp.getPayMethod();
            }
        }
        AssertUtil.isTrue(!(payMethod==1||payMethod==2),"支付方式有误");
        if (status==1){
            payMethod=null;
        }

        /**
         * orderDetails
         *
         */


        /**
         * 实收金额
            空
                状态非1
                    并且原来的订单结账时间为空，报错
            非空
                状态为1
                    设置为null
                状态非1
                    合法
         */
        if (null==amount){
            if (null==ordersTemp.getAmount()){
                AssertUtil.isTrue(status!=1,"该订单状态实收金额不能为空");
            }else {
                amount = ordersTemp.getAmount();
            }
        }
        AssertUtil.isTrue(null==amount||amount.compareTo(BigDecimal.ZERO)<=0,"实收金额有误,不能为0和负数");

        if (status==1){
            amount=null;
        }

        if (null==remark){
            remark=ordersTemp.getRemark();
        }

        OrdersEntity ordersEntity = new OrdersEntity();
        ordersEntity.setId(id);
        ordersEntity.setAddress(address);
        ordersEntity.setAmount(amount);
        ordersEntity.setOrderTime(orderTime);
        ordersEntity.setAddressBookId(addressBookId);
        ordersEntity.setCheckoutTime(checkoutTime);
        ordersEntity.setNumber(number);
        ordersEntity.setUserId(userId);
        ordersEntity.setPayMethod(payMethod);
        ordersEntity.setRemark(remark);
        ordersEntity.setPhone(phone);
        ordersEntity.setUserName(userName);
        ordersEntity.setConsignee(consignee);
        ordersEntity.setStatus(status);

        AssertUtil.isTrue(ordersDao.updateByPrimaryKeySelective(ordersEntity)<1,"添加订单失败");

        return result;
    }

    /**
     * 删除订单
     *  查看待删除记录是否存在
     * @param ids
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public Result deleteOrders(Long[] ids) {
        AssertUtils.isNull(ids,"ids为空请重试");
        for (Long id : ids) {
            AssertUtils.isNull(ordersDao.selectByPrimaryKey(id),"待删除订单不存在");
            AssertUtil.isTrue(ordersDao.deleteByPrimaryKey(id)<1,"删除订单失败");
        }

        return new Result();
    }

    /**
     *查询订单信息
     */
    public Result selectOrders(Long id) {

        Result result = new Result();

        AssertUtils.isNull(id,"订单Id为空");

        OrdersEntity ordersEntity = ordersDao.selectByPrimaryKey(id.longValue());

        result.setData(ordersEntity);

        return result;
    }

    /**
     * 分页查询订单
     * @return
     */
    public Result selectOrderDetailList(OrdersPageDTO ordersPageDTO) {
        //Integer pageSize, Integer pageNum, String order, String orderField
        Result result = new Result();

        Integer pageSize = ordersPageDTO.getLimit();
        Integer pageNum = ordersPageDTO.getPage();
        String order = ordersPageDTO.getOrder();
        String orderField = ordersPageDTO.getOrderField();
        Date beginTime = ordersPageDTO.getBeginTime();
        Date endTime = ordersPageDTO.getEndTime();
        //订单号
        String Id = ordersPageDTO.getId();

        OrdersQueryDTO ordersQueryDTO = new OrdersQueryDTO();
        ordersQueryDTO.setBeginTime(beginTime);
        ordersQueryDTO.setEndTime(endTime);
        ordersQueryDTO.setId(Id);


        // 只允许指定的排序字段和排序方式，防止2SQL注入
        String[] orderByArr = {"amount","id","number","status","order_time","checkout_time","pay_method"};
        String orderByStr = "";
        if (StringUtils.isNotEmpty(orderField) && Arrays.asList(orderByArr).contains(orderField.toLowerCase())) {
            orderByStr = String.format("%s %s", orderField.toLowerCase(), "asc".equalsIgnoreCase(order) ? "asc" : "desc");
        } else {
            // 默认排序
            orderByStr = "order_time desc";
        }

        PageHelper.startPage(pageNum, pageSize, orderByStr);
        List<OrdersEntity> ordersEntities = ordersDao.selectAllByQuery(ordersQueryDTO);
        //List<OrdersEntity> ordersEntities = ordersDao.selectAll();
        PageInfo<OrdersEntity> ordersEntitiesPageInfo = new PageInfo<>(ordersEntities);

        Map<String,Object> map = new HashMap<>();
        map.put("list",ordersEntitiesPageInfo.getList());
        int total = (int) ordersEntitiesPageInfo.getTotal();
        map.put("total",total);
        result.setData(map);

        return result;
    }
}
